package org.liang.code.jms.topic;

import jakarta.jms.JMSConsumer;
import jakarta.jms.JMSContext;
import jakarta.jms.Session;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory;
import org.liang.code.utils.jms.JMSCommons;

/**
 * 主题订阅者
 */
@Slf4j
public class TSubscriber implements Runnable{

    private final ActiveMQJMSConnectionFactory factory;
    private final String clientID;
    private final String subscriptionName;

    /**
     * 持久化订阅者
     * @param factory ActiveMQJMSConnectionFactory
     * @param clientID 同一个clientID 只能有一个线程连接消息队列 防止重复消费
     * @param subscriptionName 订阅名称
     */
    public TSubscriber(ActiveMQJMSConnectionFactory factory, String clientID, String subscriptionName) {
        this.factory = factory;
        this.clientID = clientID;
        this.subscriptionName = subscriptionName;
    }

    /**
     * 非持久化订阅者 消息队列不会为非持久化订阅者保留历史消息
     * @param factory ActiveMQJMSConnectionFactory
     */
    public TSubscriber(ActiveMQJMSConnectionFactory factory) {
        this.factory = factory;
        subscriptionName = null;
        clientID = null;
    }

    @SneakyThrows
    @Override
    public void run() {
        // 两者都不为空, 就是持久化订阅者, 消息的队列会为这个主题的地址下建立clientID:subscriptionName 的队列
        boolean durable = clientID != null && subscriptionName != null;
        if (durable) {
            factory.setClientID(clientID);
        }
        JMSConsumer consumer;

        JMSContext context = factory.createContext(Session.AUTO_ACKNOWLEDGE);
        if (durable) {
            consumer = context.createDurableConsumer(context.createTopic(JMSCommons.CORE_TOPIC), subscriptionName);
        }else {
            consumer = context.createConsumer(context.createTopic(JMSCommons.CORE_TOPIC));
        }
        if (durable) {
            log.info("持久化订阅者:{}等待消息。。。",clientID + ":" + subscriptionName);
        }else {
            log.info("临时订阅者等待消息。。。");
        }
        while (Boolean.TRUE) {
            String body = consumer.receiveBody(String.class);
            if (durable) {
                log.info("订阅者:{} 收到消息:{}", clientID + ":" + subscriptionName, body);
            }else {
                log.info("临时订阅者收到消息:{}", body);
            }
        }
        consumer.close();
        context.close();
    }
}
